/*
 * @Description:
 * @Author: fhw
 * @Date: 2023-02-17 15:49:02
 */
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Reflector } from '@nestjs/core'; // 反射器，作用与自定义装璜器桥接
import { throwHttp } from 'src/utlis';
import { isTrue } from 'src/utlis/tools';
import { RoleService } from 'src/modules/admin/role/role.service';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    private readonly reflector: Reflector,
    private readonly jwtService: JwtService,
    // private readonly roleService: RoleService,
  ) { }

  // 白名单数组
  private whiteUrlList: string[] = [];

  // 验证该次申请是否为白名单内的路由
  private isWhiteUrl(urlList: string[], url: string): boolean {
    if (urlList.includes(url)) {
      return true;
    }
    return false;
  }

  canActivate(context: ExecutionContext): boolean {
    // 获取申请对象
    const request = context.switchToHttp().getRequest();
    // 验证是否是白名单内的路由
    if (this.isWhiteUrl(this.whiteUrlList, request.url)) return true;
    // 获取申请头中的token字段，解析获取存储在token的用户信息
    const token = context
      .switchToRpc()
      .getData()
      .headers.authorization?.split(' ') as string[];
    const user: any = this.jwtService.decode(isTrue(token) ? token[1] : '');
    if (!user) throwHttp('token获取失败，请传递token或书写正确', 401);
    // 应用反射器，配合装璜器应用，获取装璜器传递过去的数据
    // 要在装潢器写入['admin']，暂时不需要
    const authRoles = this.reflector.get<string[]>(
      'rolesId',
      context.getHandler(),
    );
    // // 如果没有应用roles装璜，就获取不到值
    if (!authRoles) return true;

    // 如果用户的所属角色与装璜器传递过去的值匹配则通过，否则不通过
    const userRoles = user.roles ?? [];
    // this.roleService
    for (let i = 0; i < userRoles?.length; i++) {
      if (authRoles.includes(userRoles[i].rolename)) {
        return true;
      }
    }
    return true;
  }
}
